﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using Rhonin.Common.Extentions;

namespace ApiManage.Core.Utils
{
    public class HttpUtils
    {
        private static readonly HttpClient Http = new HttpClient();

        public static string PostJson(string url, object obj)
        {
            var content = new StringContent(obj.Serialize(), Encoding.UTF8, "application/json");
            using (var response = Http.PostAsync(url, content).Result)
            {
                response.EnsureSuccessStatusCode();
                return response.Content.ReadAsStringAsync().Result;
            }
        }
        public static string Post(string url, object obj)
        {
            var properties = GetPropertyInfos(obj);
            var keyValues = new List<KeyValuePair<string, string>>();
            foreach (var propertyInfo in properties)
            {
                var value = propertyInfo.GetValue(obj, null);
                if (value != null)
                {
                    keyValues.Add(new KeyValuePair<string, string>(propertyInfo.Name, value.ToString()));
                }
            }
            var content = new FormUrlEncodedContent(keyValues);
            using (var response = Http.PostAsync(url, content).Result)
            {
                response.EnsureSuccessStatusCode();
                return response.Content.ReadAsStringAsync().Result;
            }
        }
        public static string Get(string url, object obj)
        {
            var properties = GetPropertyInfos(obj);
            var keyValues = new List<KeyValuePair<string, string>>();
            foreach (var propertyInfo in properties)
            {
                var value = propertyInfo.GetValue(obj, null);
                if (value != null)
                {
                    keyValues.Add(new KeyValuePair<string, string>(propertyInfo.Name, value.ToString()));
                }
            }
            var paramStr = keyValues.Select(o => $"{o.Key}={o.Value}");

            //await异步等待回应
            using (var response = Http.GetAsync(url + "?" + string.Join("&", paramStr)).Result)
            {
                //确保HTTP成功状态值
                response.EnsureSuccessStatusCode();
                //await异步读取最后的JSON（注意此时gzip已经被自动解压缩了，因为上面的AutomaticDecompression = DecompressionMethods.GZip）
                return response.Content.ReadAsStringAsync().Result;
            }
        }
        private static IEnumerable<PropertyInfo> GetPropertyInfos(object obj)
        {
            return obj == null ? new List<PropertyInfo>() : obj.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public).ToList();
        }
        /// <summary>
        /// HttpPost基础
        /// </summary>
        /// <param name="url">请求Url</param>
        /// <param name="postDataStr">Post参数</param>
        /// <param name="herders">请求头</param>
        /// <param name="host">代理Host</param>
        /// <param name="contentType">参数类型</param>
        /// <returns></returns>
        public static string HttpPost(string url, string postDataStr, Dictionary<string, string> herders = null, string host = null, string contentType = "application/json;charset=UTF-8")
        {
            try
            {
                var byteArray = Encoding.UTF8.GetBytes(postDataStr);
                var request = (HttpWebRequest)WebRequest.Create(url); //发送地址
                request.Method = "POST"; //提交方式
                if (herders != null && herders.Count != 0)
                {
                    foreach (var (key, value) in herders)
                    {
                        request.Headers.Add(key, value);
                    }
                }
                if (!string.IsNullOrEmpty(host))
                {
                    if (host.Contains(":"))
                    {
                        var ip = host.Split(":")[0];
                        var port = Convert.ToInt32(host.Split(":")[1]);
                        request.Proxy = new WebProxy(ip, port);
                    }
                    else
                    {
                        request.Proxy = new WebProxy(host);
                    }
                }
                if (!string.IsNullOrEmpty(contentType))
                {
                    request.ContentType = contentType;
                }
                request.ContentLength = byteArray.Length;
                var newStream = request.GetRequestStream();
                newStream.Write(byteArray, 0, byteArray.Length); //写入参数
                newStream.Close();

                var response = (HttpWebResponse)request.GetResponse(); //获取响应
                var sr = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
                return sr.ReadToEnd(); // 返回的数据
            }
            catch (WebException e)
            {
                WebResponse wenReq = (HttpWebResponse)e.Response;
                var sr = new StreamReader(wenReq.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
                return sr.ReadToEnd();
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }
        /// <summary>
        /// httpGet基础
        /// </summary>
        /// <param name="url">请求Url</param>
        /// <param name="herders">请求头</param>
        /// <param name="host">代理Host</param>
        /// <param name="contentType">参数类型</param>
        /// <returns></returns>
        public static string HttpGet(string url, Dictionary<string, string> herders = null, string host = null,string contentType =null)
        {
            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                if (herders != null && herders.Count != 0)
                {
                    foreach (var (key, value) in herders)
                    {
                        request.Headers.Add(key, value);
                    }
                }
                request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
                if (host != null)
                {
                    if (host.Contains(":"))
                    {
                        var ip = host.Split(":")[0];
                        var port = Convert.ToInt32(host.Split(":")[1]);
                        request.Proxy = new WebProxy(ip, port);
                    }
                    else
                    {
                        request.Proxy = new WebProxy(host);
                    }
                }
                if (!string.IsNullOrEmpty(contentType))
                {
                    request.ContentType = contentType;
                }
                var response = (HttpWebResponse)request.GetResponse();
                var myResponseStream = response.GetResponseStream();
                var myStreamReader = new StreamReader(myResponseStream ?? throw new InvalidOperationException(), Encoding.GetEncoding("utf-8"));
                var retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();

                return retString;
            }
            catch (WebException e)
            {
                WebResponse wenReq = (HttpWebResponse)e.Response;
                var sr = new StreamReader(wenReq.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
                return sr.ReadToEnd();
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }
    }
}
